﻿using NPOI.HPSF;
using NPOI.HSSF.UserModel;
using NPOI.SS.Converter;
using NPOI.SS.UserModel;
using NPOI.SS.Util;
using NPOI.XSSF.UserModel;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BlueFox.Common.Utilities
{
    /// <summary>
    /// Excel 工具
    /// </summary>
    public class ExcelHelper
    {
        //private string templateFile = null;
        //private string outputFile = null;
        //private HSSFWorkbook hssfWorkbook;
        //private ISheet sheet;

        public static DataTable GetDataTableByOleDb(string fileName, string tableName)
        {

            if (string.IsNullOrEmpty(fileName)) { throw new ArgumentException("fileName"); }
            if (string.IsNullOrEmpty(tableName)) { throw new ArgumentException("tableName"); }

            OleDbConnection conn = null;
            try
            {
                DataSet dataSet = new DataSet();
                string strCon = " Provider = Microsoft.Jet.OLEDB.4.0 ; Data Source = " + fileName + ";Extended Properties='Excel 8.0;HDR=NO;IMEX=1';";
                conn = new OleDbConnection(strCon);
                string strCom = " SELECT *FROM [" + tableName + "$] ";
                conn.Open();

                OleDbDataAdapter command = new OleDbDataAdapter(strCom, conn);
                command.Fill(dataSet, "[" + tableName + "$]");
                conn.Close();
                System.Data.DataTable dt = new System.Data.DataTable();
                dt = dataSet.Tables[0];
                return dt;
            }
            catch
            {
                conn.Close();
                throw;
            }
        }

        public static DataTable GetDataTable(string excel, int index, bool header)
        {
            DataTable dt = new DataTable(Path.GetFileNameWithoutExtension(excel) + "_Sheet" + index);
            var ext = Path.GetExtension(excel);
            IWorkbook workbook;
            using (FileStream file = new FileStream(excel, FileMode.Open, FileAccess.Read))
            {
                if (ext == ".xlsx")
                {
                    workbook = new XSSFWorkbook(file);
                }
                else
                {
                    workbook = new HSSFWorkbook(file);
                }
            }
            ISheet sheet = workbook.GetSheetAt(index);
            var rows = sheet.GetRowEnumerator();

            IRow headerRow = sheet.GetRow(0);//第一行为标题行
            int rowcount = sheet.LastRowNum;
            int headCount = headerRow.Cells.Count;//列数

            rows.MoveNext();
            IRow row = (IRow)rows.Current;

            for (int i = 0; i < headCount; i++)
            {
                ICell cell = row.GetCell(i);
                string columnName = header ? cell.StringCellValue : i.ToString();
                dt.Columns.Add(columnName, typeof(string));
            }
            if (!header)
            {
                DataRow first = dt.NewRow();
                for (int i = 0; i < headCount; i++)
                {
                    ICell cell = row.GetCell(i);
                    first[i] = cell.StringCellValue;
                }
                dt.Rows.Add(first);
            }

            while (rows.MoveNext())
            {
                row = (IRow)rows.Current;
                DataRow dataRow = dt.NewRow();

                for (int i = 0; i < headCount; i++)
                {
                    ICell cell = row.GetCell(i);
                    var cellValue = "";
                    if (cell != null)
                    {
                        cellValue = cell.ToString();
                    }
                    if (cellValue == "NULL")
                    {
                        cellValue = "";
                    }
                    dataRow[i] = cellValue;
                }
                dt.Rows.Add(dataRow);
            }

            return dt;
        }


        /// <summary>
        /// DataTable导出到Excel的MemoryStream
        /// </summary>
        /// <param name="dtSource">源DataTable</param>
        /// <param name="strHeaderText">表头文本</param>
        public static MemoryStream ExportMemoryStream(DataTable dtSource, string strHeaderText)
        {
            HSSFWorkbook workbook = new HSSFWorkbook();
            ISheet sheet = workbook.CreateSheet();

            #region 右击文件 属性信息
            {
                DocumentSummaryInformation dsi = PropertySetFactory.CreateDocumentSummaryInformation();
                dsi.Company = "NPOI";
                workbook.DocumentSummaryInformation = dsi;

                SummaryInformation si = PropertySetFactory.CreateSummaryInformation();
                si.Author = "文件作者信息"; //填加xls文件作者信息
                si.ApplicationName = "创建程序信息"; //填加xls文件创建程序信息
                si.LastAuthor = "最后保存者信息"; //填加xls文件最后保存者信息
                si.Comments = "作者信息"; //填加xls文件作者信息
                si.Title = "标题信息"; //填加xls文件标题信息
                si.Subject = "主题信息";//填加文件主题信息
                si.CreateDateTime = DateTime.Now;
                workbook.SummaryInformation = si;
            }
            #endregion

            HSSFCellStyle dateStyle = (HSSFCellStyle)workbook.CreateCellStyle();
            HSSFDataFormat format = (HSSFDataFormat)workbook.CreateDataFormat();
            dateStyle.DataFormat = format.GetFormat("yyyy-mm-dd");

            //取得列宽

            int[] arrColWidth = new int[dtSource.Columns.Count];
            foreach (DataColumn item in dtSource.Columns)
            {
                arrColWidth[item.Ordinal] = Encoding.GetEncoding(936).GetBytes(item.ColumnName.ToString()).Length;
            }
            for (int i = 0; i < dtSource.Rows.Count; i++)
            {
                for (int j = 0; j < dtSource.Columns.Count; j++)
                {
                    int intTemp = Encoding.GetEncoding(936).GetBytes(dtSource.Rows[i][j].ToString()).Length;
                    if (intTemp > arrColWidth[j])
                    {
                        arrColWidth[j] = intTemp;
                    }
                }
            }
            int rowIndex = 0;
            foreach (DataRow row in dtSource.Rows)
            {
                #region 新建表，填充表头，填充列头，样式
                if (rowIndex == 65535 || rowIndex == 0)
                {
                    if (rowIndex != 0)
                    {
                        sheet = (HSSFSheet)workbook.CreateSheet();
                    }

                    #region 表头及样式
                    {
                        HSSFRow headerRow = (HSSFRow)sheet.CreateRow(0);
                        headerRow.HeightInPoints = 25;
                        headerRow.CreateCell(0).SetCellValue(strHeaderText);

                        HSSFCellStyle headStyle = (HSSFCellStyle)workbook.CreateCellStyle();
                        //headStyle.Alignment = CellHorizontalAlignment.CENTER;
                        HSSFFont font = (HSSFFont)workbook.CreateFont();
                        font.FontHeightInPoints = 20;
                        font.Boldweight = 700;
                        headStyle.SetFont(font);
                        headerRow.GetCell(0).CellStyle = headStyle;
                        sheet.AddMergedRegion(new CellRangeAddress(0, 0, 0, dtSource.Columns.Count - 1));
                        //headerRow.Dispose();
                    }
                    #endregion


                    #region 列头及样式
                    {
                        HSSFRow headerRow = (HSSFRow)sheet.CreateRow(1);
                        HSSFCellStyle headStyle = (HSSFCellStyle)workbook.CreateCellStyle();

                        HSSFFont font = (HSSFFont)workbook.CreateFont();
                        font.FontHeightInPoints = 10;
                        font.Boldweight = 700;
                        headStyle.SetFont(font);
                        foreach (DataColumn column in dtSource.Columns)
                        {
                            headerRow.CreateCell(column.Ordinal).SetCellValue(column.ColumnName);
                            headerRow.GetCell(column.Ordinal).CellStyle = headStyle;
                            //设置列宽
                            sheet.SetColumnWidth(column.Ordinal, (arrColWidth[column.Ordinal] + 3) * 256);
                        }
                        //headerRow.Dispose();
                    }
                    #endregion

                    rowIndex = 2;
                }
                #endregion


                #region 填充内容
                IRow dataRow = sheet.CreateRow(rowIndex);
                foreach (DataColumn column in dtSource.Columns)
                {
                    HSSFCell newCell = (HSSFCell)dataRow.CreateCell(column.Ordinal);

                    string drValue = row[column].ToString();

                    switch (column.DataType.ToString())
                    {
                        case "System.String"://字符串类型
                            newCell.SetCellValue(drValue);
                            break;
                        case "System.DateTime"://日期类型
                            DateTime dateV;
                            DateTime.TryParse(drValue, out dateV);
                            newCell.SetCellValue(dateV);

                            newCell.CellStyle = dateStyle;//格式化显示
                            break;
                        case "System.Boolean"://布尔型
                            bool boolV = false;
                            bool.TryParse(drValue, out boolV);
                            newCell.SetCellValue(boolV);
                            break;
                        case "System.Int16"://整型
                        case "System.Int32":
                        case "System.Int64":
                        case "System.Byte":
                            int intV = 0;
                            int.TryParse(drValue, out intV);
                            newCell.SetCellValue(intV);
                            break;
                        case "System.Decimal"://浮点型
                        case "System.Double":
                            double doubV = 0;
                            double.TryParse(drValue, out doubV);
                            newCell.SetCellValue(doubV);
                            break;
                        case "System.DBNull"://空值处理
                            newCell.SetCellValue("");
                            break;
                        default:
                            newCell.SetCellValue("");
                            break;
                    }

                }
                #endregion

                rowIndex++;
            }
            using (MemoryStream ms = new MemoryStream())
            {
                workbook.Write(ms);
                ms.Flush();
                ms.Position = 0;

                //sheet.Dispose();
                //workbook.Dispose();//一般只用写这一个就OK了，他会遍历并释放所有资源，但当前版本有问题所以只释放sheet
                return ms;
            }
        }

        /// <summary>
        /// excel转html
        /// </summary>
        /// <returns></returns>
        public static string Excel2Html(string excel)
        {
            string result;
            var workbook = ExcelToHtmlUtils.LoadXls(excel);
            ExcelToHtmlConverter conver = new ExcelToHtmlConverter();
            conver.OutputColumnHeaders = false;
            conver.OutputHiddenColumns = false;
            conver.OutputHiddenRows = false;
            conver.OutputLeadingSpacesAsNonBreaking = false;
            conver.OutputRowNumbers = false;
            conver.UseDivsToSpan = false;

            //process the excel file
            conver.ProcessWorkbook(workbook);
            using (MemoryStream ms = new MemoryStream())
            {
                conver.Document.Save(ms);
                byte[] bs = ms.ToArray();
                result = Encoding.UTF8.GetString(bs);
            }
            return result;
        }

    }
}
